package IO;/*
 *
 * @author 陈粒
 * @version 创建时间：2021/7/16 11:31
 */
/**
 * 缓冲流-BufferedInputStream、BufferedOutputStream：
 * 总结：
 * BufferedInputStream 是缓冲输入流。它继承于FilterInputStream。
 *
 * BufferedInputStream 的作用是为另一个输入流添加一些功能，例如，提供“缓冲功能”以及支持mark()标记和reset()重置方法。
 *
 * BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如，在新建某输入流对应的BufferedInputStream后，
 * 当我们通过read()读取输入流的数据时，BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后，输入流会再次填充数据缓冲区；如此反复，直到我们读完输入流数据位置。
 *
 * 注意点：
 * 1.BufferedOutputStream在close()时会自动flush
 * 2.BufferedOutputStream在不调用close()的情况下，缓冲区不满，又需要把缓冲区的内容写入到文件或通过网络发送到别的机器时，才需要调用flush
 */

import org.junit.Test;

import java.io.*;

public class Buffered_Input_Output_Stream {//复制文件

    @Test
    public void testinput_outputBufferStream() {
        File fileold = new File("C:\\Users\\tarena\\Desktop\\file\\Cat1.png");//旧文件路径
        File filenew = new File("C:\\Users\\tarena\\Desktop\\file\\Cat2.png");//新文件路径，新文件可以不存在
        copyfile(fileold, filenew);//调用自写的方法
    }

    public void copyfile(File fileold, File filenew) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        //创建四种输入、输出流对象
        try {
            fis = new FileInputStream(fileold);
            fos = new FileOutputStream(filenew);
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            byte[] bytes = new byte[1024];//代表一次最多读取1024k的内容，缓冲区
            int i = 0;//代表实际读取的字节数
            while ((i = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, i);//bytes：数组，off：我的理解，接收数据的数组的开始下标,相对正确的说法，接收数据的数组（或叫缓冲区）的偏移量的下标开始位置
                //i:我的理解，要传入的用来存储数据的变量，相对正确的说法，是要读取字节数的长度
            }
            bos.flush();//刷新BufferoutputStream的缓冲区，把没写出的数据强制写出
        } catch (FileNotFoundException e) {
            System.out.println("找不到该文件");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();//BufferedOutputStream在close()时会自动flush
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}